package cn.net.Reflection;
/*
测试暴力反射
 */
import org.junit.Test;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**暴力反射不需要遍历数组*/
public class TestReflection2 {
    //一、单元测试暴力反射设置并获取私有属性值
    @Test/*暴力反射；获取私有属性值及类型+创建对象+重新设置/获取私有的属性值*/
    public void getFiled() throws Exception {
        Class<?> clazz = Person.class;
        Field f = clazz.getDeclaredField("name");//暴力获取私有属性"name"；
        //3.获取属性对象和属性类型
        System.out.println(f.getName());//name
        System.out.println(f.getType());//class java.lang.String
        System.out.println(f.getType().getName());//java.lang.String

        //4.1 没有对象就通过反射的方式创建对象
        Object o = clazz.newInstance();
        //4.2暴力反射前提:访问属性值【必须设置私有可见】
        f.setAccessible(true);
        //4.3设置属性的值set(m,n)---m为对象obj，n为具体属性值value
        f.set(o,"大大");
        //5.获取刚设置的私有属性值
        System.out.println(f.get(o));//get需要打印
    }
    @Test  /*二.单元测试，暴力反射获取和设置私有方法*/
    public void getMethod() throws Exception {
        Class<?> clazz = Person.class;
        /*getDeclaredMethod(m, x,y,z...)
         * m:"方法名" + x,y,z...可变参数，但注意要加“参数类型.class”
         */ //2.通过暴力反射获取私有方法
        Method m = clazz.getDeclaredMethod("save", int.class, String.class);
        //通过反射方式创建对象
        Object o = clazz.newInstance();//触发无参方法
        //3.2 想要执行私有方法，也需要先设置私有可见
        m.setAccessible(true);
        /*invoke(o,x,y,z...),表示通过反射技术执行方法
         * o :要执行的是哪个对象的方法
         * x,y,z...:执行这个方法【method对象代表的之前获取到的save()】时需要传入的参数
         * */
        //3.3 通过反射技术invoke()，执行目标对象obj的目标方法method【save()】
          m.invoke(o,15,"开开");
    }

}
